package com.example.codegenerator.domain.impl;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSONObject;
import com.example.codegenerator.common.config.GeneratorConfig;
import com.example.codegenerator.common.constant.file.FilePathConstant;
import com.example.codegenerator.common.constant.file.PackageInfoConstant;
import com.example.codegenerator.common.constant.global.GeneratorConstant;
import com.example.codegenerator.common.constant.global.GlobalConstant;
import com.example.codegenerator.common.constant.obj.GeneratorMapConstant;
import com.example.codegenerator.common.constant.obj.ObjectSuffixNameConstant;
import com.example.codegenerator.common.model.bo.TableGeneratorBO;
import com.example.codegenerator.common.model.bo.TableInfoBO;
import com.example.codegenerator.common.model.dto.GeneratorDTO;
import com.example.codegenerator.common.sources.BuildFactory;
import com.example.codegenerator.common.utils.GeneratorUtils;
import com.example.codegenerator.domain.DatabaseDomainApplication;
import com.example.codegenerator.domain.GeneratorDomainApplication;
import com.example.codegenerator.service.GeneratorService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletResponse;
import javax.swing.text.html.Option;
import java.io.*;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.example.codegenerator.common.constant.file.FilePathConstant.SRC_DIR_PATH;
import static com.example.codegenerator.common.constant.global.GeneratorConstant.AUTHOR;
import static com.example.codegenerator.common.constant.global.GeneratorConstant.TABLE_NAME_LIST;

/**
 * 代码生成 领域层 具体实现
 *
 * @author lvshengyu
 * @date 2023/8/17
 */
@Slf4j
@Component
public class GeneratorDomainApplicationImpl implements GeneratorDomainApplication {
    /**
     * 填充构建信息
     *
     * @param tableName 表名称
     * @return
     */
    @Override
    public Map<String, Object> getFillDataMap(String tableName) {
        // 获取数据表填充信息
        Map<String, Object> tableInfoMap = getTableInfoMap(tableName);
        // 处理全局填充信息
        Map<String, Object> globalObjectMap = GeneratorUtils.newHashMap();
        globalObjectMap.put(GeneratorMapConstant.TABLE, tableInfoMap);
        globalObjectMap.put(GeneratorMapConstant.REST_CONTROLLER_STYLE, Boolean.TRUE);
        filGlobalStrategy(globalObjectMap, tableInfoMap, tableName);
        return globalObjectMap;
    }

    /**
     * 逻辑删除标识符
     */
    @Value("${generator.table-delete-logic-flag}")
    private String logicDeleteFlag;

    /**
     * 默认逻辑删除标识符
     */
    private static final String DEFAULT_LOGIC_DELETE_FLAG = "delete_flag";

    /**
     * 填充全局策略配置信息
     *
     * @param globalObjectMap 全局配置map容器
     * @param tableInfoMap    数据表map容器
     * @param tableName       表名称
     */
    private void filGlobalStrategy(Map<String, Object> globalObjectMap, Map<String, Object> tableInfoMap, String tableName) {
        globalObjectMap.put(GlobalConstant.DATE, GeneratorUtils.localDateNow());
        globalObjectMap.put(GlobalConstant.ENTITY_LOMBOK_MODEL, Boolean.TRUE);
        globalObjectMap.put(GlobalConstant.SWAGGER, Boolean.TRUE);

        // 处理逻辑删除标识符
        logicDeleteFlag = Optional.ofNullable(logicDeleteFlag).orElse(DEFAULT_LOGIC_DELETE_FLAG);
        globalObjectMap.put(GlobalConstant.LOGIC_DELETE_FIELD_NAME, logicDeleteFlag);

        globalObjectMap.put(GlobalConstant.ENABLE_CACHE, Boolean.FALSE);
        globalObjectMap.put(GlobalConstant.BASE_RESULT_MAP, Boolean.TRUE);
        globalObjectMap.put(GlobalConstant.BASE_COLUMN_LIST, Boolean.TRUE);
        globalObjectMap.put(GlobalConstant.SUPER_MAPPER_CLASS, GlobalConstant.BASE_MAPPER);
        globalObjectMap.put(GlobalConstant.SUPER_MAPPER_CLASS_PACKAGE, PackageInfoConstant.BASE_MAPPER_IMPORT_PACKAGES);
        globalObjectMap.put(GlobalConstant.SUPER_SERVICE_CLASS, GlobalConstant.I_SERVICE);
        globalObjectMap.put(GlobalConstant.SUPER_SERVICE_CLASS_PACKAGE, PackageInfoConstant.BASE_SERVICE_IMPORT_PACKAGES);
        globalObjectMap.put(GlobalConstant.SUPER_SERVICE_IMPL_CLASS_PACKAGE, PackageInfoConstant.BASE_SERVICE_IMPL_IMPORT_PACKAGES);
        globalObjectMap.put(GlobalConstant.SUPER_SERVICE_IMPL_CLASS, GlobalConstant.SERVICE_IMPL);

        String apiPath = GeneratorUtils.toUnderScoreCase(GeneratorUtils.toCamelCase(tableName));
        globalObjectMap.put(GlobalConstant.API_PATH, apiPath);

        String filedNames = getFiledNames(tableInfoMap);
        globalObjectMap.put(GlobalConstant.FILED_NAMES, filedNames);
    }

    /**
     * 获取查询字段信息
     *
     * @param tableInfoMap 数据表map容器
     * @return
     */
    @SuppressWarnings("all")
    private String getFiledNames(Map<String, Object> tableInfoMap) {
        List<TableGeneratorBO> tableGeneratorBOList = (List<TableGeneratorBO>) tableInfoMap.get(GeneratorMapConstant.FIELDS);
        return tableGeneratorBOList.stream().map(TableGeneratorBO::getName).collect(Collectors.joining(","));
    }

    /**
     * 获取数据表填充信息
     *
     * @param tableName 数据表名称
     * @return
     */
    private Map<String, Object> getTableInfoMap(String tableName) {
        Map<String, Object> tableInfoMap = GeneratorUtils.newHashMap();
        // 填充字段信息（包括字段属性名称 类型 导入包）
        fillFieldsMap(tableInfoMap, tableName);
        // 填充对象信息
        fillObjectNameMap(tableInfoMap, tableName);
        // 填充包路径信息
        fillPackagesInfoMap(tableInfoMap, tableName);
        return tableInfoMap;
    }

    /**
     * 填充包信息
     *
     * @param tableInfoMap 数据表配置信息map容器
     * @param tableName    数据表名称
     */
    private void fillPackagesInfoMap(Map<String, Object> tableInfoMap, String tableName) {
        tableInfoMap.put(GeneratorMapConstant.PACKAGE, generatorConfig.initPackages());
        tableInfoMap.put(GeneratorMapConstant.NAME, tableName);
        tableInfoMap.put(GeneratorMapConstant.COMMON_FIELDS, new ArrayList<>());
    }

    @Autowired
    private BuildFactory buildFactory;

    /**
     * 填充对象名称信息
     *
     * @param tableInfoMap 数据表配置信息map容器
     * @param tableName    数据表名称
     */
    private void fillObjectNameMap(Map<String, Object> tableInfoMap, String tableName) {
        String mapperName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.MAPPER);
        tableInfoMap.put(GeneratorMapConstant.MAPPER_NAME, mapperName);
        tableInfoMap.put(GeneratorMapConstant.XML_NAME, mapperName);

        String serviceName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.SERVICE);
        tableInfoMap.put(GeneratorMapConstant.SERVICE_NAME, serviceName);

        String serviceImplName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.SERVICE + ObjectSuffixNameConstant.IMPL);
        tableInfoMap.put(GeneratorMapConstant.SERVICE_IMPL_NAME, serviceImplName);

        String providerName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.PROVIDER);
        tableInfoMap.put(GeneratorMapConstant.PROVIDER_NAME, providerName);

        String providerImpl = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.PROVIDER + ObjectSuffixNameConstant.IMPL);
        tableInfoMap.put(GeneratorMapConstant.PROVIDER_IMPL_NAME, providerImpl);

        String facadeName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.FACADE);
        tableInfoMap.put(GeneratorMapConstant.FACADE_NAME, facadeName);

        String controllerApiName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.CONTROLLER_API);
        tableInfoMap.put(GeneratorMapConstant.CONTROLLER_API_NAME, controllerApiName);

        String controllerName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.CONTROLLER);
        tableInfoMap.put(GeneratorMapConstant.CONTROLLER_NAME, controllerName);

        String dtoName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.DTO);
        tableInfoMap.put(GeneratorMapConstant.DTO_NAME, dtoName);

        String voName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.VO);
        tableInfoMap.put(GeneratorMapConstant.VO_NAME, voName);

        String boName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.BO);
        tableInfoMap.put(GeneratorMapConstant.BO_NAME, boName);

        String doName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.DO);
        tableInfoMap.put(GeneratorMapConstant.DO_NAME, doName);

        String vueName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.VUE);
        tableInfoMap.put(GeneratorMapConstant.VUE_NAME, vueName);

        String jsName = buildFactory.buildTargetObjectName(tableName, ObjectSuffixNameConstant.JS);
        tableInfoMap.put(GeneratorMapConstant.JS_NAME, jsName);

        String mapperObjectName = GeneratorUtils.toObjectName(mapperName);
        tableInfoMap.put(GeneratorMapConstant.MAPPER_OBJECT_NAME, mapperObjectName);

        String serviceObjectName = GeneratorUtils.toObjectName(serviceName);
        tableInfoMap.put(GeneratorMapConstant.SERVICE_OBJECT_NAME, serviceObjectName);
    }

    @Autowired
    private DatabaseDomainApplication databaseDomainApplication;

    /**
     * 填充对象信息（包括字段属性名称 类型 导入包）
     *
     * @param tableInfoMap 数据表配置信息map容器
     * @param tableName    数据表名称
     */
    private void fillFieldsMap(Map<String, Object> tableInfoMap, String tableName) {
        List<TableInfoBO> tableInfoBOList = databaseDomainApplication.loadTableInfo(tableName);
        Assert.notEmpty(tableInfoBOList, "表名称有误");
        List<TableGeneratorBO> tableGeneratorBOList = convertToTableGeneratorBO(tableInfoBOList);

        tableInfoMap.put(GeneratorMapConstant.FIELDS, tableGeneratorBOList);

        // 添加序列化导入包
        Set<String> objImportPackages = listImportPackages(tableGeneratorBOList);
        tableInfoMap.put(GeneratorMapConstant.OBJ_IMPORT_PACKAGES, objImportPackages);

        // 添加mybatis-plus导入包
        Set<String> importPackages = listImportPackages(tableGeneratorBOList);
        importPackages.addAll(generatorConfig.initMybatisPlusImportPackages());
        tableInfoMap.put(GeneratorMapConstant.IMPORT_PACKAGES, importPackages);

        // 填充表描述信息
        tableInfoMap.put(GeneratorMapConstant.TABLE_COMMENT, databaseDomainApplication.getTableComment(tableName));
        tableInfoMap.put(GeneratorMapConstant.TABLE_CONVERT, Boolean.TRUE);
    }

    /**
     * 通过字段属性类型获取导入包信息
     *
     * @param tableGeneratorBOList 代码生成数据表业务对象
     * @return
     */
    private Set<String> listImportPackages(List<TableGeneratorBO> tableGeneratorBOList) {
        Set<String> set = tableGeneratorBOList.stream().map(item -> generatorConfig.initFiledTypeImportMap().get(item.getPropertyType()))
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        set.addAll(generatorConfig.initSerializableImportPackages());
        return set;
    }

    @Autowired
    private GeneratorConfig generatorConfig;

    /**
     * 获取构建字段信息
     *
     * @param tableInfoBOList 数据表信息
     * @return
     */
    private List<TableGeneratorBO> convertToTableGeneratorBO(List<TableInfoBO> tableInfoBOList) {
        return tableInfoBOList.stream().map(item -> {
            TableGeneratorBO tableGeneratorBO = new TableGeneratorBO();
            tableGeneratorBO.setKeyIdentityFlag(GlobalConstant.AUTO_INCREMENT.equalsIgnoreCase(item.getExtra()));
            tableGeneratorBO.setColumnType(item.getDataType());
            tableGeneratorBO.setPropertyName(GeneratorUtils.toCamelCase(item.getColumnName()));
            tableGeneratorBO.setName(item.getColumnName());
            tableGeneratorBO.setPropertyType(generatorConfig.initTypeMap().get(item.getDataType().toUpperCase()));
            tableGeneratorBO.setComment(item.getColumnComment());
            tableGeneratorBO.setConvert(Boolean.TRUE);
            tableGeneratorBO.setFill(getFiledFill(item));
            tableGeneratorBO.setKeyFlag(GlobalConstant.PRI_FLAG.equalsIgnoreCase(item.getColumnKey()));
            return tableGeneratorBO;
        }).collect(Collectors.toList());
    }

    /**
     * 创建时间字段标识
     */
    @Value("${generator.table-insert-time-flag}")
    private String insertFlag;

    /**
     * 修改时间字段标识
     */
    @Value("${generator.table-update-time-flag}")
    private String updateFlag;

    /**
     * 默认创建时间字段标识
     */
    private static final String DEFAULT_INSERT_FLAG = "create_time";

    /**
     * 默认修改时间字段标识
     */
    private static final String DEFAULT_update_FLAG = "update_time";

    /**
     * 获取字段填充信息
     *
     * @param tableInfoBO 数据表信息
     * @return
     */
    private String getFiledFill(TableInfoBO tableInfoBO) {
        // 健壮性处理 防止NPE
        insertFlag = Optional.ofNullable(insertFlag).orElse(DEFAULT_INSERT_FLAG);
        updateFlag = Optional.ofNullable(updateFlag).orElse(DEFAULT_update_FLAG);

        if (insertFlag.equalsIgnoreCase(tableInfoBO.getColumnName())) {
            return GlobalConstant.CREATE_TIME_FLAG;
        } else if (updateFlag.equalsIgnoreCase(tableInfoBO.getColumnName())) {
            return GlobalConstant.UPDATE_TIME_FLAG;
        } else {
            return null;
        }
    }

    /**
     * 代码生成（项目路径方式）
     *
     * @param generatorDTO 代码生成数据传递对象
     * @return
     */
    @Override
    public Boolean generator(GeneratorDTO generatorDTO) {
        fillGeneratorDTO(generatorDTO);
        // 通过反射获取字段名称 获取对应处理策略
        Field[] declaredFields = generatorDTO.getClass().getDeclaredFields();

        dealDeclaredFields(declaredFields);
        List<Field> fieldValueIsTrueList = getTrueFiled(declaredFields, generatorDTO);
        log.info("fieldValueIsTrueList :{}", JSONObject.toJSONString(fieldValueIsTrueList));

        List<String> tableNameList = generatorDTO.getTableNameList();
        Assert.notEmpty(tableNameList, "表名称不能为空");

        String author = generatorDTO.getAuthor();
        Assert.notNull(author, "作者名称不能为空");
        log.info("用于代码生成数据表:{}  作者:{}", tableNameList, author);

        tableNameList.forEach(table -> {
            Map<String, Object> dataMap = getFillDataMap(table);
            // 设置作者信息
            dataMap.put(GeneratorConstant.AUTHOR, author);
            // 设置是否需要controllerApi
            dataMap.put(GeneratorConstant.IF_CONTROLLER_API, generatorDTO.getControllerApi());
            // 调用代码生成逻辑
            fieldValueIsTrueList.forEach(item -> generatorCode(item.getName(), dataMap));
        });
        return Boolean.TRUE;
    }

    /**
     * 代码生成（云端下载方式）
     *
     * @param generatorDTO        代码生成数据传递对象
     * @param httpServletResponse http响应对象
     * @return
     */
    @Override
    public Boolean generatorCodeDownload(GeneratorDTO generatorDTO, HttpServletResponse httpServletResponse) {
        // 生成代码
        Boolean generator = generator(generatorDTO);
        Assert.isTrue(generator, "代码生成错误");

        // 压缩代码文件为zip
        Boolean convert = convertFolderToZip();
        Assert.isTrue(convert, "压缩代码文件错误");

        // 下载代码压缩文件并删除压缩包
        Boolean download = downloadZipFile(httpServletResponse);
        Assert.isTrue(download, "下载代码压缩文件错误");

        // 删除生成文件
        Boolean remove = removeFile();
        Assert.isTrue(remove, "删除生成文件错误");
        return Boolean.TRUE;
    }

    /**
     * 是否删除代码生成临时文件 (true删除  false不删除)
     */
    @Value("${generator.delete}")
    private Boolean deleteTempFile;

    /**
     * 删除生成文件
     */
    private Boolean removeFile() {
        // 获取代码生成路径
        String generatorFolderPath = getGeneratorFolderPath();
        // 过滤处理出删除路径
        String deletePath = filterDeletePath(generatorFolderPath);

        // 提升健壮性
        deleteTempFile = Optional.ofNullable(deleteTempFile).orElse(Boolean.FALSE);
        if (deleteTempFile) {
            // 删除代码文件
            FileUtil.del(deletePath);
        }
        return Boolean.TRUE;
    }

    /**
     * 过滤出删除路径
     *
     * @param generatorFolderPath 代码生成路径
     * @return
     */
    private String filterDeletePath(String generatorFolderPath) {
        String[] split = generatorFolderPath.split("/");

        // 处理获取src路径
        List<String> pathList = new ArrayList<>();
        for (String path : split) {
            pathList.add(path);
            if (FilePathConstant.SRC_PATH.equals(path)) {
                break;
            }
        }

        String deletePath = String.join("/", pathList);
        log.info("文件删除路径 :{}", deletePath);
        return deletePath;
    }

    /**
     * 下载代码压缩文件并删除压缩包
     */
    private Boolean downloadZipFile(HttpServletResponse httpServletResponse) {
        File file = new File(getGeneratorFolderPath() + GeneratorConstant.FILE_FORMAT);
        OutputStream toClient = null;
        try {
            // 以流的形式下载文件。
            BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[bufferedInputStream.available()];
            bufferedInputStream.read(buffer);
            bufferedInputStream.close();
            // 清空response
            httpServletResponse.reset();
            toClient = new BufferedOutputStream(httpServletResponse.getOutputStream());
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setContentType("application/octet-stream");
            httpServletResponse.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
            toClient.write(buffer);
            toClient.flush();
        } catch (Exception e) {
            log.error("下载zip压缩包过程发生异常:", e);
        } finally {
            if (toClient != null) {
                try {
                    toClient.close();
                } catch (IOException e) {
                    log.error("zip包下载关流失败:", e);
                }
            }
            // 删除压缩文件
            FileUtil.del(getGeneratorFolderPath() + GeneratorConstant.FILE_FORMAT);
        }
        return Boolean.TRUE;
    }

    /**
     * 处理代码文件夹
     */
    private Boolean convertFolderToZip() {
        String folderPath = getGeneratorFolderPath();
        dealFile(folderPath, folderPath + GeneratorConstant.FILE_FORMAT);
        return Boolean.TRUE;
    }

    /**
     * 压缩文件预处理
     *
     * @param folderPath  文件夹路径
     * @param zipFilePath 压缩包文件路径
     */
    @SneakyThrows
    private void dealFile(String folderPath, String zipFilePath) {
        File folderFile = new File(folderPath);
        FileOutputStream fileOutputStream = new FileOutputStream(zipFilePath);
        ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);
        // 压缩文件夹
        try {
            zipFolder(folderFile, folderFile.getName(), zipOutputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭输出流
            zipOutputStream.close();
        }
    }

    /**
     * 压缩文件夹
     *
     * @param folderFile      源文件对象
     * @param parentFolder    源文件夹名称
     * @param zipOutputStream 压缩文件输出流
     */
    @SuppressWarnings("all")
    @SneakyThrows
    private void zipFolder(File folderFile, String parentFolder, ZipOutputStream zipOutputStream) {
        for (File file : folderFile.listFiles()) {
            if (file.isDirectory()) {
                zipFolder(file, parentFolder + "/" + file.getName(), zipOutputStream);
            } else {
                ZipEntry zipEntry = new ZipEntry(parentFolder + "/" + file.getName());
                zipOutputStream.putNextEntry(zipEntry);

                try (FileInputStream fileInputStream = new FileInputStream(file)) {
                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len = fileInputStream.read(buffer)) > 0) {
                        zipOutputStream.write(buffer, 0, len);
                    }
                }
            }
        }
    }

    /**
     * 获取代码生成文件夹目录
     *
     * @return
     */
    private String getGeneratorFolderPath() {
        return GeneratorConfig.getProjectPath() + SRC_DIR_PATH + FilePathConstant.FILE_DIR_PATH;
    }

    @Autowired
    private Map<String, GeneratorService> generatorServiceMap;

    /**
     * 策略模式构建具体代码
     *
     * @param key     构建对象实例化策略key
     * @param dataMap 代码生成填充信息
     * @return
     */
    private Boolean generatorCode(String key, Map<String, Object> dataMap) {
        GeneratorService generatorService = generatorServiceMap.get(key);
        return (generatorService == null) ? Boolean.TRUE : generatorService.generator(dataMap);
    }

    /**
     * 获取字段属性值为true的字段
     *
     * @param declaredFields 字段数组
     * @param generatorDTO   代码生成数据传递对象
     * @return
     */
    private List<Field> getTrueFiled(Field[] declaredFields, GeneratorDTO generatorDTO) {
        return Arrays.stream(declaredFields)
                .filter(item -> !TABLE_NAME_LIST.equals(item.getName()))
                .filter(item -> !AUTHOR.equals(item.getName()))
                .filter(item -> checkBoolean(item, generatorDTO))
                .collect(Collectors.toList());
    }

    /**
     * 校验参数值是否为true
     *
     * @param field        字段属性
     * @param generatorDTO 代码生成数据传递对象
     * @return
     */
    @SneakyThrows
    private boolean checkBoolean(Field field, GeneratorDTO generatorDTO) {
        return Boolean.TRUE.equals(field.get(generatorDTO));
    }

    /**
     * 处理字段属性数组  (访问标志设为true可访问)
     *
     * @param declaredFields 字段属性数组
     * @return
     */
    private void dealDeclaredFields(Field[] declaredFields) {
        Arrays.stream(declaredFields).forEach(item -> item.setAccessible(true));
    }

    /**
     * 填充代码生成数据传递对象  为空则默认true
     *
     * @param generatorDTO 代码生成数据传递对象
     */
    private void fillGeneratorDTO(GeneratorDTO generatorDTO) {
        generatorDTO.setController(Optional.ofNullable(generatorDTO.getController()).orElse(Boolean.TRUE));
        generatorDTO.setService(Optional.ofNullable(generatorDTO.getService()).orElse(Boolean.TRUE));
        generatorDTO.setServiceImpl(Optional.ofNullable(generatorDTO.getServiceImpl()).orElse(Boolean.TRUE));
        generatorDTO.setEntity(Optional.ofNullable(generatorDTO.getEntity()).orElse(Boolean.TRUE));
        generatorDTO.setMapper(Optional.ofNullable(generatorDTO.getMapper()).orElse(Boolean.TRUE));
        generatorDTO.setMapperXml(Optional.ofNullable(generatorDTO.getMapperXml()).orElse(Boolean.TRUE));
        generatorDTO.setProvider(Optional.ofNullable(generatorDTO.getProvider()).orElse(Boolean.TRUE));
        generatorDTO.setProviderImpl(Optional.ofNullable(generatorDTO.getProviderImpl()).orElse(Boolean.TRUE));
        generatorDTO.setFacade(Optional.ofNullable(generatorDTO.getFacade()).orElse(Boolean.TRUE));
        generatorDTO.setDomainApplication(Optional.ofNullable(generatorDTO.getDomainApplication()).orElse(Boolean.TRUE));
        generatorDTO.setControllerApi(Optional.ofNullable(generatorDTO.getControllerApi()).orElse(Boolean.TRUE));
        generatorDTO.setDto(Optional.ofNullable(generatorDTO.getDto()).orElse(Boolean.TRUE));
        generatorDTO.setVo(Optional.ofNullable(generatorDTO.getVo()).orElse(Boolean.TRUE));
        generatorDTO.setBo(Optional.ofNullable(generatorDTO.getBo()).orElse(Boolean.TRUE));
        generatorDTO.setVue(Optional.ofNullable(generatorDTO.getVue()).orElse(Boolean.TRUE));
        generatorDTO.setJs(Optional.ofNullable(generatorDTO.getJs()).orElse(Boolean.TRUE));
    }
}
